home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-05 / src_1218.zip / AX25HDR.C < prev    next >
C/C++ Source or Header  |  1991-01-27  |  3KB  |  110 lines

  1. /* AX25 header conversion routines
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. #include "global.h"
  5. #include "mbuf.h"
  6. #include "ax25.h"
  7.  
  8. /* Convert a host-format AX.25 header into a mbuf ready for transmission */
  9. struct mbuf *
  10. htonax25(hdr,data)
  11. register struct ax25 *hdr;
  12. struct mbuf *data;
  13. {
  14.     struct mbuf *bp;
  15.     register char *cp;
  16.     register int16 i;
  17.  
  18.     if(hdr == (struct ax25 *)NULL || hdr->ndigis > MAXDIGIS)
  19.         return NULLBUF;
  20.  
  21.     /* Allocate space for return buffer */
  22.     i = AXALEN * (2 + hdr->ndigis);
  23.     if((bp = pushdown(data,i)) == NULLBUF)
  24.         return NULLBUF;
  25.  
  26.     /* Now convert */
  27.     cp = bp->data;        /* cp -> dest field */
  28.  
  29.     /* Generate destination field */
  30.     memcpy(cp,hdr->dest,AXALEN);
  31.     if(hdr->cmdrsp == LAPB_COMMAND)
  32.         cp[ALEN] |= C;    /* Command frame sets C bit in dest */
  33.     else
  34.         cp[ALEN] &= ~C;
  35.     cp[ALEN] &= ~E;    /* Dest E-bit is always off */
  36.  
  37.     cp += AXALEN;        /* cp -> source field */
  38.  
  39.     /* Generate source field */
  40.     memcpy(cp,hdr->source,AXALEN);
  41.     if(hdr->cmdrsp == LAPB_RESPONSE)
  42.         cp[ALEN] |= C;
  43.     else
  44.         cp[ALEN] &= ~C;
  45.     /* Set E bit on source address if no digis */
  46.     if(hdr->ndigis == 0){
  47.         cp[ALEN] |= E;
  48.         return bp;
  49.     }
  50.  
  51.     cp += AXALEN;        /* cp -> first digi field */
  52.  
  53.     /* All but last digi get copied with E bit off */
  54.     for(i=0; i < hdr->ndigis; i++){
  55.         memcpy(cp,hdr->digis[i],AXALEN);
  56.         if(i < hdr->ndigis - 1)
  57.             cp[ALEN] &= ~E;
  58.         else
  59.             cp[ALEN] |= E;    /* Last digipeater has E bit set */
  60.         if(i < hdr->nextdigi)
  61.             cp[ALEN] |= REPEATED;
  62.         else
  63.             cp[ALEN] &= ~REPEATED;
  64.         cp += AXALEN;        /* cp -> next digi field */
  65.     }
  66.     return bp;
  67. }
  68. /* Convert a network-format AX.25 header into a host format structure
  69.  * Return -1 if error, number of addresses if OK
  70.  */
  71. int
  72. ntohax25(hdr,bpp)
  73. register struct ax25 *hdr;    /* Output structure */
  74. struct mbuf **bpp;
  75. {
  76.     register char *axp;
  77.  
  78.     if(pullup(bpp,hdr->dest,AXALEN) < AXALEN)
  79.         return -1;
  80.  
  81.     if(pullup(bpp,hdr->source,AXALEN) < AXALEN)
  82.         return -1;
  83.  
  84.     /* Process C bits to get command/response indication */
  85.     if((hdr->source[ALEN] & C) == (hdr->dest[ALEN] & C))
  86.         hdr->cmdrsp = LAPB_UNKNOWN;
  87.     else if(hdr->source[ALEN] & C)
  88.         hdr->cmdrsp = LAPB_RESPONSE;
  89.     else
  90.         hdr->cmdrsp = LAPB_COMMAND;
  91.  
  92.     hdr->ndigis = 0;
  93.     hdr->nextdigi = 0;
  94.     if(hdr->source[ALEN] & E)
  95.         return 2;    /* No digis */
  96.  
  97.     /* Count and process the digipeaters */
  98.     axp = hdr->digis[0];
  99.     while(hdr->ndigis < MAXDIGIS && pullup(bpp,axp,AXALEN) == AXALEN){
  100.         hdr->ndigis++;
  101.         if(axp[ALEN] & REPEATED)
  102.             hdr->nextdigi++;
  103.         if(axp[ALEN] & E)    /* Last one */
  104.             return hdr->ndigis + 2;            
  105.         axp += AXALEN;
  106.     }
  107.     return -1;    /* Too many digis */
  108. }
  109.  
  110.